package com.coalmine.iec104.modules.handle;

import com.coalmine.iec104.config.constant.IecConfig;
import lombok.extern.slf4j.Slf4j;
import org.openmuc.j60870.*;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import java.io.IOException;

/**
 * @Author mkq
 * @Date 2023-11-01 9:17
 * @Description
 */
@Slf4j
@Component
@ConditionalOnProperty(name = "iec104.useServer", havingValue = "true")
public class IEC104ServerHandle {

    @Resource
    private IecConfig iecConfig;

    Server server104;

    Connection serverConnection;

    @PostConstruct
    public void init() {
        server104 = Server.builder().setPort(iecConfig.getServerPort()).build();
        try {
            server104.start(new ServerListenerImpl());
            log.info("iec104服务启动成功,端口为:" + iecConfig.getServerPort());
        } catch (IOException e) {
            log.error("iec104服务启动失败" + e.getMessage(), e);
        }
    }

    private class ServerListenerImpl implements ServerEventListener {

        @Override
        public ConnectionEventListener setConnectionEventListenerBeforeStart() {
            return new ServerReceiver();
        }

        @Override
        public void connectionIndication(Connection connection) {
            serverConnection = connection;
        }

        @Override
        public void serverStoppedListeningIndication(IOException e) {
        }

        @Override
        public void connectionAttemptFailed(IOException e) {
        }

    }

    private class ServerReceiver implements ConnectionEventListener {

        @Override
        public void newASdu(ASdu aSdu) {
            log.info("服务端收到消息:" + aSdu);
            try {
                if (aSdu.getCauseOfTransmission() == CauseOfTransmission.ACTIVATION) {
                    serverConnection.sendConfirmation(aSdu);
                }
            } catch (IOException e) {
                log.error("服务端收到消息后发送确认信息失败", e);
            }
        }

        @Override
        public void connectionClosed(IOException e) {

        }

        @Override
        public void dataTransferStateChanged(boolean b) {

        }

    }

    @PreDestroy
    public void close() {
        if (server104 != null) {
            server104.stop();
        }
    }

}
